package com.tbit.uqbike.webmanager.business.user_op_log.service;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tbit.common.entity.MachineOpLog;
import com.tbit.common.entity.UserOpLog;
import com.tbit.common.utils.TraceUtil;
import com.tbit.config.datasource.DataSource;
import com.tbit.common.entity.view.PageResult;
import com.tbit.uqbike.webmanager.business.machine_op_log.object.dto.MachineOpLogPageReq;
import com.tbit.uqbike.webmanager.business.user_op_log.dao.log.UserOpLogDao;
import com.tbit.uqbike.webmanager.business.user_op_log.object.dto.UserOpLogPageReq;
import com.tbit.uqbike.webmanager.dao.core.AccountDao;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

import static com.tbit.common.entity.UserOpLog.Fields;

/**
 * @author <a href="mailto:zheng.zebiao@tbit.com.cn">zb</a>
 * @since 2024/11/26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserOpLogService extends ServiceImpl<UserOpLogDao, UserOpLog> {
    private static ThreadLocal<Integer> brandIdThreadLocal = new ThreadLocal<>();

    final AccountDao accountDao;

    public PageResult<UserOpLog> getRecordList(UserOpLogPageReq req) {
        Integer brandId = brandIdThreadLocal.get();
        if (Objects.isNull(brandId)) {
            brandId = accountDao.getBrandIdByAccountIdV2(req.getAccountId());
        }
        brandIdThreadLocal.remove();
        QueryWrapper<UserOpLog> queryWrapper = Wrappers.query(UserOpLog.class)
                .in(Fields.accountId, req.getAccountId(), brandId)
                .eq(req.getOpPlatform() != null, Fields.opPlatform, req.getOpPlatform())
                .eq(req.getOperation() != null, Fields.operation, req.getOperation())
                .eq(req.getOpUser() != null, Fields.opUser, req.getOpUser())
                .eq(req.getOpUserPhone() != null, Fields.opUserPhone, req.getOpUserPhone())
                .eq(req.getTargetUser() != null, Fields.targetUser, req.getTargetUser())
                .eq(req.getTargetUserPhone() != null, Fields.targetUserPhone, req.getTargetUserPhone())
                .between(req.getStartTime() != null && req.getEndTime() != null, Fields.opTime, req.getStartTime(), req.getEndTime())
                .orderByDesc(Fields.opTime);

        return PageResult.convertPage(
                getBaseMapper().selectPage(Page.of(req.getPageNO(), req.getRowCount()), queryWrapper)
        );
    }

    public void insertSingle(UserOpLog userOpLog) {
        try {
            StringBuilder detail = new StringBuilder(ObjectUtil.defaultIfNull(userOpLog.getDetail(), ""));
            String traceId = TraceUtil.getTraceIdByLocal();
            if (traceId != null) {
                if (detail.length() > 0) {
                    detail.append("\n");
                }
                detail.append("TraceID: ")
                        .append(traceId);
            }
            userOpLog.setDetail(detail.length() > 0 ? detail.toString() : null);
            getBaseMapper().insert(userOpLog);
        } catch (Exception e) {
            log.error("[人员操作日志] 插入失败: {}", userOpLog, e);
        }
    }

    @DS(DataSource.LOG)
    public void insertBatch(List<UserOpLog> userOpLogs) {
        try {
            String traceId = TraceUtil.getTraceIdByLocal();
            if (traceId != null) {
                for (UserOpLog opLog : userOpLogs) {
                    StringBuilder detail = new StringBuilder(ObjectUtil.defaultIfNull(opLog.getDetail(), ""));
                    if (detail.length() > 0) {
                        detail.append("\n");
                    }
                    detail.append("TraceID: ")
                            .append(traceId);
                    opLog.setDetail(detail.length() > 0 ? detail.toString() : null);
                }
            }
            saveBatch(userOpLogs);
        } catch (Exception e) {
            log.error("[人员操作日志] 批量插入失败，失败条数: {}", userOpLogs.size(), e);
        }
    }

    /**
     * @description: 查询数据量
     * @author: mo.shanyong
     * @date: 2025/3/17 15:44
     * @param: re
     */
    public int getCount(UserOpLogPageReq req){
        Integer brandId = accountDao.getBrandIdByAccountIdV2(req.getAccountId());
        brandIdThreadLocal.set(brandId);
        QueryWrapper<UserOpLog> queryWrapper = Wrappers.query(UserOpLog.class)
                .in(Fields.accountId, req.getAccountId(), brandId)
                .eq(req.getOpPlatform() != null, Fields.opPlatform, req.getOpPlatform())
                .eq(req.getOperation() != null, Fields.operation, req.getOperation())
                .eq(req.getOpUser() != null, Fields.opUser, req.getOpUser())
                .eq(req.getOpUserPhone() != null, Fields.opUserPhone, req.getOpUserPhone())
                .eq(req.getTargetUser() != null, Fields.targetUser, req.getTargetUser())
                .eq(req.getTargetUserPhone() != null, Fields.targetUserPhone, req.getTargetUserPhone())
                .between(req.getStartTime() != null && req.getEndTime() != null, Fields.opTime, req.getStartTime(), req.getEndTime());
        Long count = getBaseMapper().selectCount(queryWrapper);
        return Objects.isNull(count) ? 0 : count.intValue();
    }
}
